<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

if ( !function_exists('ippi_set_current_member') ){
    /**
     * set the current member by ID.
     *
     * Some IPPI functionality is based on the current member and not based on
     * the signed in member. Therefore, it opens the ability to edit and perform
     * actions on members who aren't signed in.
     *
     * @param   int     $id     Member ID
     * @return  IPPI_Member Current member IPPI_Member object
     */
    function ippi_set_current_member($id)
    {
    	$CI =& get_instance();
    
    	$current_member = $CI->ippi_member->member($id);
        unset($current_member->password);
    
    	return $current_member;
    }
}

if ( !function_exists('ippi_get_current_member') ){
    /**
     * Retrieve the current member object.
     *
     * @return IPPI_Member Current member IPPI_Member object
     */
    function ippi_get_current_member() 
    {
        $CI =& get_instance();
        if(!empty($CI->current_member)) return $CI->current_member;
        
    	$current_member = get_currentmemberinfo();
       
    	if ( !$current_member ){
    		if ($id = ippi_isset($_COOKIE['logged_in_'.md5('nonssl')], false, true)){
                $member     = $CI->model_member->get_memberdata($id);
        		if ($member->login == 1)
                    return ippi_set_current_member($id);
        	}
    		return false;
    	}
    	return $current_member;
    }
}

if ( !function_exists('get_currentmemberinfo') ){
    /**
     * Populate global variables with information about the currently logged in member.
     *
     * Will set the current member, if the current member is not set. The current member
     * will be set to the logged in person. If no member is logged in, then it will
     * set the current member to 0, which is invalid and won't have any permissions.
     *
     * @uses ippi_validate_auth_cookie() Retrieves current logged in member.
     *
     */
    function get_currentmemberinfo() {
    	
    	if ( !$id_member = ippi_validate_auth_cookie() ) {
    		 if ( empty($_COOKIE[LOGGED_IN_COOKIE]) || !$id_member = ippi_validate_auth_cookie($_COOKIE[LOGGED_IN_COOKIE], 'logged_in') ) {
    		 	ippi_set_current_member(0);
    		 	return false;
    		 }
    	}
    
    	return ippi_set_current_member($id_member);
    }
}

if ( !function_exists('ippi_validate_auth_cookie') ){
    /**
     * Validates authentication cookie.
     *
     * The checks include making sure that the authentication cookie is set and
     * pulling in the contents (if $cookie is not used).
     *
     * Makes sure the cookie is not expired. Verifies the hash in cookie is what is
     * should be and compares the two.
     *
     * @param string $cookie Optional. If used, will validate contents instead of cookie's
     * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
     * @return bool|int False if invalid cookie, Member ID if valid.
     */
    
    function ippi_validate_auth_cookie( $cookie = '', $scheme = '' )
    {
    	if ( !$cookie_elements = ippi_parse_auth_cookie($cookie, $scheme) )
    		return false;
            
    	extract($cookie_elements, EXTR_OVERWRITE);
    
    	$expired = $expiration;
    
    	if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) 
    		$expired += 3600;
    
    	if ( $expired < time() )
    		return false;
    
    	$CI =& get_instance();
    
    	$member = $CI->model_member->get_member_by('email', $email);
        
    	if ( !$member || empty($member)) 
    		return false;
    
    	$pass_frag = substr($member->password, 8, 4);
    	$key       = ippi_hash($email . $pass_frag . '|' . $expiration, $scheme);
    	$hash      = hash_hmac('md5', $email . '|' . $expiration, $key);
    	
    	if ( $hmac != $hash )
    		return false;
    
    	return $member->id_member;
    }
}

if ( !function_exists('ippi_parse_auth_cookie') ){
    /**
     * Parse a cookie into its components
     *
     * @param string $cookie
     * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
     * @return array Authentication cookie components
     */
    function ippi_parse_auth_cookie($cookie = '', $scheme = '')
    {
    	$CI =& get_instance();
    
    	if( empty($cookie) ) {
    		switch ($scheme) {
    			case 'auth':
                    $cookie_name        = AUTH_COOKIE;
    				break;
    			case 'secure_auth':
                    $cookie_name        = SECURE_AUTH_COOKIE;
                    break;
    			case 'logged_in':
                    $cookie_name        = LOGGED_IN_COOKIE;
    				break;
    			default:
    				if ( is_ssl() ) {
                        $cookie_name    = SECURE_AUTH_COOKIE;
                        $scheme         = 'secure_auth';
    				} else {
                        $cookie_name    = AUTH_COOKIE;
                        $scheme         = 'auth';
    				}
                    break;
    		}
    
    		if ( empty($_COOKIE[$cookie_name]) )
    			return false;
    		$cookie = $_COOKIE[$cookie_name];
    	}
    
    	$cookie_elements = explode('|', $cookie);
    	if ( count($cookie_elements) != 4 )
    		return false;
    
    	list($email, $expiration, $hmac, $id_member) = $cookie_elements;
    
    	return compact('email', 'expiration', 'hmac', 'id_member', 'scheme');
    }
}

if ( !function_exists('ippi_set_auth_cookie') ){
    /**
     * Sets the authentication cookies based Member ID.
     *
     * The $remember parameter increases the time that the cookie will be kept. The
     * default the cookie is kept without remembering is two days. When $remember is
     * set, the cookies will be kept for 14 days or two weeks.
     *
     *
     * @param int $id_member Member ID
     * @param bool $remember Whether to remember the member
     */
    
    function ippi_set_auth_cookie( $id_member, $remember = false, $secure = '' )
    {    
        $CI =& get_instance();
        
    	if ( $remember ) {
            $expiration = $expire = 2147483647; // maximum expired value (PHP limitation)
    	} else {
    		$expiration = time() + 172800;
    		$expire = 0;
    	}
        
        if ( '' === $secure )
    		$secure = is_ssl();
    
    	if ( $secure ) {
            $auth_cookie_name   = SECURE_AUTH_COOKIE;
            $scheme             = 'secure_auth';
    	} else {
            $auth_cookie_name   = AUTH_COOKIE;
            $scheme             = 'auth';
    	}
    
        $auth_cookie            = ippi_generate_auth_cookie($id_member, $expiration, $scheme);
        $logged_in_cookie       = ippi_generate_auth_cookie($id_member, $expiration, 'logged_in');
        
    	if(preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', base_url(), $regs)){
            $cookie_domain      = '.' . $regs['domain'];
    	}else{
            $cookie_domain      = str_replace(array('http://', 'https://', 'www.'), '', base_url());
            $cookie_domain      = '.' . str_replace('/', '', $cookie_domain);
    	}
        
    	$cookie = array(
    		'name'   => $auth_cookie_name,
    		'value'  => $auth_cookie,
    		'expire' => $expire,
    		'path'   => '/',
    		'domain' => $cookie_domain,
    		'secure' => false
    	);
        
    	$CI->input->set_cookie($cookie);
     
    	unset($cookie);
    	
    	$cookie = array(
    		'name'   => LOGGED_IN_COOKIE,
    		'value'  => $logged_in_cookie,
    		'expire' => $expire,
    		'path'   => '/',
    		'domain' => $cookie_domain,
    		'secure' => false
    	);
        
    	$CI->input->set_cookie($cookie);
    }
}

if ( !function_exists('ippi_clear_auth_cookie') ){
    /**
     * Removes all of the cookies associated with authentication.
     *
     * @since 2.5
     */
    function ippi_clear_auth_cookie()
    {
        $CI =& get_instance();
        $logged = false;
        
    	if(preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', base_url(), $regs))
            $cookie_domain  = '.'.$regs['domain'];
        else{
            $cookie_domain  = str_replace(array('http://', 'https://', 'www.'), '', base_url());
            $cookie_domain  = '.'.str_replace('/', '', $cookie_domain);
        }
        
        $id_member  = ippi_get_current_member_id();
        if ( !$id_member ){
        	if ($id = ippi_isset($_COOKIE['logged_in_'.md5('nonssl')], false, true)){
                $member     = $CI->model_member->get_memberdata($id);
                if($member->login == 1) $logged = true;
        	}
        }else{
            $logged = true;
        }

    	if( $logged ) {
    	   
        	$CI =& get_instance();
            
            $member     = ippi_get_current_member();
            
            $name       = 'last_login_'.strtolower(date('F'));
            $cookie     = array(
                'name'      => md5($name),
                'value'     => $member->id_member.'-'.time(),
                'expire'    => time()+60*60*24*30,
                'path'      => '/',
                'domain'    => $cookie_domain,
                'secure'    => false
        	);
            
        	$CI->input->set_cookie($cookie);
        }
        
    	setcookie(AUTH_COOKIE, ' ', time() - 31536000, '/', $cookie_domain);
    	setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, '/', $cookie_domain);
    	setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, '/', $cookie_domain);
    
    	// Old cookies
    	setcookie(AUTH_COOKIE, ' ', time() - 31536000, '/', $cookie_domain);
    	setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, '/', $cookie_domain);
    
    	// Even older cookies
    	setcookie(MEMBER_COOKIE, ' ', time() - 31536000, '/', $cookie_domain);
    	setcookie(PASS_COOKIE, ' ', time() - 31536000, '/', $cookie_domain);
    	
    	// Logged in unsecure
    	setcookie('logged_in_'.md5('nonssl'), ' ', time() - 31536000, '/', $cookie_domain);
    }
}


if ( !function_exists('ippi_generate_auth_cookie') ){
    /**
     * Generate authentication cookie contents.
     *
     * @param int       $id_member      (Required)      Member ID
     * @param int       $expiration     (Required)      Cookie expiration in seconds
     * @param string    $scheme         (Optional}      The cookie scheme to use: auth, secure_auth, or logged_in
     * @return string Authentication cookie contents
     */
    function ippi_generate_auth_cookie($id_member, $expiration, $scheme = 'auth') {
    	$CI =& get_instance();
    
    	$member    = $CI->model_member->get_memberdata($id_member);
    	$pass_frag = substr($member->password, 8, 4);
    
    	$key       = ippi_hash($member->email . $pass_frag . '|' . $expiration, $scheme);
    	$hash      = hash_hmac('md5', $member->email . '|' . $expiration, $key);
    
    	$cookie    = $member->email . '|' . $expiration . '|' . $hash . '|' . $id_member;
    
    	return $cookie;
    }
}

if ( !function_exists('ippi_hash') ){
    /**
     * Get hash of given string.
     *
     * @uses ippi_salt() Get IPPI salt
     *
     * @param   string $data Plain text to hash
     * @return  string Hash of $data
     */
    function ippi_hash($data, $scheme = 'auth') {
    	$salt = ippi_salt($scheme);
    
    	return hash_hmac('md5', $data, $salt);
    }
}

if ( !function_exists('ippi_salt') ){
    /**
     * Get salt to add to hashes to help prevent attacks.
     *
     * @param   string $scheme Authentication scheme
     * @return  string Salt value
     */
    function ippi_salt($scheme = 'auth') {
    
    	$CI =& get_instance();
    
    	$secret_key = $CI->config->item('encryption_key');
    
    	if ( 'auth' == $scheme ) {
    		if ( defined('AUTH_KEY') && ('' != AUTH_KEY) )
    			$secret_key = AUTH_KEY;
    
    		if ( defined('AUTH_SALT') && ('' != AUTH_SALT) ) {
    			$salt = AUTH_SALT;
    		}
    	} else if ( 'secure_auth' == $scheme ) {
    		if ( defined('SECURE_AUTH_KEY') && ('' != SECURE_AUTH_KEY) )
    			$secret_key = SECURE_AUTH_KEY;
    
    		if ( defined('SECURE_AUTH_SALT') && ('' != SECURE_AUTH_SALT) ) {
    			$salt = SECURE_AUTH_SALT;
    		}
    	} else if ( 'logged_in' == $scheme ) {
    		if ( defined('LOGGED_IN_KEY') && ('' != LOGGED_IN_KEY) )
    			$secret_key = LOGGED_IN_KEY;
    
    		if ( defined('LOGGED_IN_SALT') && ('' != LOGGED_IN_SALT) ) {
    			$salt = LOGGED_IN_SALT;
    		}
    	} else if ( 'nonce' == $scheme ) {
    		if ( defined('NONCE_KEY') && ('' != NONCE_KEY) )
    			$secret_key = NONCE_KEY;
    
    		if ( defined('NONCE_SALT') && ('' != NONCE_SALT) ) {
    			$salt = NONCE_SALT;
    		}
    	} else {
    		// ensure each auth scheme has its own unique salt
    		$salt = hash_hmac('md5', $scheme, $secret_key);
    	}
    
    	return $secret_key . $salt;
    }
}

if ( !function_exists('is_member_logged_in') ){
    /**
     * Checks if the current visitor is a logged in user.
     *
     * @return bool True if user is logged in, false if not logged in.
     */
    function is_member_logged_in()
    {		
        $CI =& get_instance();
        $id_member  = ippi_get_current_member_id();
        
        if ( !$id_member ){
        	if ($id = ippi_isset($_COOKIE['logged_in_'.md5('nonssl')], false, true)){
                $member     = $CI->model_member->get_memberdata($id);
                $id_member  = $member->id_member;
        	}
            return false;
        }
        
        if( !empty($id_member) ){
            update_last_activity($id_member);
        }
        
    	return true;
    }
}

if (!function_exists('ippi_get_last_logged_in')){
    /**
     * Get last login member via cookies
     * @return member id
     */
    function ippi_get_last_logged_in(){
    	$CI 	=& get_instance();
    	$name 	= 'last_login_'.strtolower(date('F'));
    	$cookie = $CI->input->cookie($name);
    	
    	if(!$cookie) return false;
    	
    	return $cookie;
    }
}

if (!function_exists('ippi_get_memberdata_by_id')){
    /**
     * Get member data by id
     *
     * @param integer $id Member ID
     * @return (object) member data
     */
    function ippi_get_memberdata_by_id($id){
    	$CI =& get_instance();
    	return $CI->model_member->get_memberdata($id);
    }
}

if (!function_exists('as_active_member')){
    /**
     * 
     * Is current member is active member
     * @param Object $member
     * @return bool
     */
    function as_active_member( $member ){	
        if( !empty($member) ){
            return ( $member->status == 1 );
        }
        return false;
    }
}

if (!function_exists('as_administrator')){
    /**
     * 
     * Is current member is administrator
     * @param Object $member
     * @return bool
     */
    function as_administrator( $member ){
    	if (!$member)
    		return false;
        
        $CI =& get_instance();
        $member = $CI->ippi_member->member($member->id_member);
    		
    	return ( ($member->level == 2) );	
    }
}

if (!function_exists('ippi_get_current_member_id')){
    /**
     * 
     * Get current logged in member id
     * @param none
     * @return integer member id
     */
    function ippi_get_current_member_id(){
    	$auth_cookie = ippi_parse_auth_cookie( ippi_isset( $_COOKIE[LOGGED_IN_COOKIE] ), 'logged_in');
        
    	if( !is_array($auth_cookie) ) return false;
    	
    	return $auth_cookie['id_member'];
    }
}

if (!function_exists('check_member_login')){
    /**
     * 
     * Check member login status and last activity
     * @param int       $id_member  (Required)  Member ID
     * @param string    $type       (Optional)  Type for check login status, can be empty to process if not login
     * @return mixed bool (true) if from login process, bool (false) and redirect uri for other
     */
    function check_member_login($id_member, $type=''){
        $CI =& get_instance();
        
        $response       = 0;
        
        if( !$id_member || empty($id_member) ) return $response;
        
        $auto           = ( !empty($type) || $type == 'auto' ? true : false );
        $member         = $CI->model_member->get_memberdata($id_member);
        
        if( !$member ) return $response;
        
        $login_stat     = $member->login;
        $last_activity  = strtotime($member->last_activity);
        $now            = time();
        $logtime        = get_option('logtime');
        
        if( $login_stat > 0 ){
            $activity_time  = $now - $last_activity;
            
            if($activity_time > $logtime){
                auto_logout();
                
                $login_update   = array( 'login' => 0 );
                $CI->model_member->update_data($id_member, $login_update);
                
                if( $auto ) $response = 2;
                else        $response = 1;
            }else{
                if( $auto ) $response = 1;
                else        $response = 2;
            }
        }elseif( $login_stat == 0){
            $response   = 1;
        }
        
        return $response;
    }
}

if (!function_exists('auto_logout')){
    /**
     * Auto logout
     * @param none
     * @return void
     */
    function auto_logout(){
        $CI =& get_instance();
        
        if( ippi_isset($CI->session->userdata('member_logged_in')) ){
            $CI->session->unset_userdata('member_logged_in');
            $CI->session->sess_destroy();
        }
        
        ippi_clear_auth_cookie();
    }
}

if (!function_exists('update_last_activity')){
    /**
     * Update last activity time
     * @param int   $id_member  (Required)  Member ID
     * @return mixed, void if success, bool (false) if failed
     */
    function update_last_activity($id_member){
        $CI =& get_instance();
        
        if( !$id_member || empty($id_member) ) return false;
        
        $last_activity  = date('Y-m-d H:i:s', time() );
        $login_update   = array( 'last_activity' => $last_activity );

        $CI->model_member->update_data($id_member, $login_update);
    }
}

/*
CHANGELOG
---------
Insert new changelog at the top of the list.
-----------------------------------------------
Version	YYYY/MM/DD  Person Name		Description
-----------------------------------------------
1.0.0   2014/09/01  Ahmad           - Revised function force_to_wizard()
*/